package com.lagou.edu.listener;


import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.annotation.Transactional;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wuyancheng
 */
public class ScanPackage {

    private static final String CLASS = ".class";

    private List<String> classPaths = new ArrayList<>();

    private List<String> beanClassNameList = new ArrayList<>();

    public Map<String, BeanDefinition> doLoadBeanDefinition(String packageName) throws ClassNotFoundException {
        doScanPackage(packageName);
        Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
        for (String beanClassname : beanClassNameList) {
            Class<?> bean = Class.forName(beanClassname);
            Service annotation = bean.getAnnotation(Service.class);
            if(annotation != null){
                BeanDefinition beanDefinition = new BeanDefinition();
                String beanName;
                //如果service注解配置了属性值，使用配置的属性值做为bean的id
                if(!"".equals(annotation.value())){
                    beanName = annotation.value();
                } else {
                    //未配置属性，使用类名做为bean的id
                    String[] split = beanClassname.split("\\.");
                    beanName = split[split.length - 1];
                    beanName = beanName.replaceFirst(beanName.substring(0,1),beanName.substring(0,1).toLowerCase());
                }
                beanDefinition.setBeanClassName(beanClassname);
                beanDefinition.setAlias(beanName);

                Field[] fields = bean.getDeclaredFields();
                for (Field field : fields) {
                    if(field.getAnnotation(Autowired.class) != null){
                        String filedName = field.getName();
                        filedName = filedName.replaceFirst(filedName.substring(0,1),filedName.substring(0,1).toUpperCase());
                        beanDefinition.getPropertyMap().put(filedName, field.getType().getName());
                    }
                }

                Method[] methods = bean.getMethods();
                for (Method method : methods) {
                    if(method.getAnnotation(Transactional.class) != null){
                        beanDefinition.setTransactional(true);
                    }
                }

                Transactional transactional = bean.getAnnotation(Transactional.class);
                if(transactional != null){
                    beanDefinition.setTransactional(true);
                }
                beanDefinitionMap.put(beanDefinition.getBeanClassName(), beanDefinition);
            }

        }
        return beanDefinitionMap;
    }

    public void doScanPackage(String packageName) throws ClassNotFoundException {
        String classpath = this.getClass().getResource("/").getPath();
        packageName = packageName.replace(".", File.separator);
        String searchPath = classpath + packageName;
        classpath=classpath.substring(1);
        doGetPath(new File(searchPath));
        for (String  beanClassname : classPaths) {
            beanClassname = beanClassname.replace("\\", "/");
            beanClassname = beanClassname.replace(classpath, "").replace("/", ".")
                    .replace(CLASS, "");
            beanClassNameList.add(beanClassname);
        }
    }

    private void doGetPath(File file) {
        if (file.isDirectory()) {
            //如果是文件夹进行递归
            File[] files = file.listFiles();
            for (File temp : files) {
                doGetPath(temp);
            }
        } else {
            //如果是文件，判断是否是class文件
            if (file.getName().endsWith(CLASS)) {
                classPaths.add(file.getPath());
            }
        }
    }

}
